﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public static class UnityFunctions  {

    public static void ClearList(List<Transform> _list)
    {
        if (_list != null)
        {
            for (int i = 0; i < _list.Count; i++)
            {
#if UNITY_EDITOR
                if (_list[i] != null)
                    GameObject.DestroyImmediate(_list[i].gameObject);
#endif
                if (_list[i] != null)
                    GameObject.Destroy(_list[i].gameObject);

            }
            _list.Clear();
        }
    }


    public static void ClearList(List<GameObject> _list)
    {
        if (_list != null)
        {
            for (int i = 0; i < _list.Count; i++)
            {
#if UNITY_EDITOR
                if (_list[i] != null)
                    GameObject.DestroyImmediate(_list[i].gameObject);
#endif
                if (_list[i] != null)
                    GameObject.Destroy(_list[i].gameObject);

            }
            _list.Clear();
        }
    }

    public static void ClearList<T>(List<T> _list) where T : MonoBehaviour
    {
        if (_list != null)
        {
            for (int i = 0; i < _list.Count; i++)
            {
#if UNITY_EDITOR
                if (_list[i] != null)
                    GameObject.DestroyImmediate(_list[i].gameObject);
#endif
                if (_list[i] != null)
                    GameObject.Destroy(_list[i].gameObject);

            }
            _list.Clear();
        }
    }

    public static double GetTimeStampSeconds()
    {
        TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0);
        return ts.TotalSeconds;
    }

    public static DateTime TimeStampSeconds2DateTime(double timeStamp)
    {
        return new DateTime(1970, 1, 1, 0, 0, 0).AddSeconds(timeStamp);
    }
    
    /// <summary>
    /// 时间转换天时分秒显示
    /// </summary>
    /// <returns>The stamp to HM.</returns>
    /// <param name="seconds">seconds</param>
    public static string TimeToDHMS(double secondsd)
    {
        var seconds = (int)secondsd;
        var day = seconds / 86400;
        var secondsInDay = seconds % 86400;
        var hour = secondsInDay / 3600;
        var minute = (secondsInDay - hour * 3600) / 60;
        var second = secondsInDay - hour * 3600 - minute * 60;
        if (day > 0)
        {
            return string.Format("{0}d {1:D2}:{2:D2}:{3:D2}", day, hour, minute, second);
        }
        else
        {
            return string.Format("{0:D2}:{1:D2}:{2:D2}", hour, minute, second);
        }
    }

    public static string TimeToMS(double secondsd)
    {
        var seconds = (int)secondsd;
        var minute = seconds / 60;
        var second = seconds - minute * 60;
        return string.Format("{0:D2}:{1:D2}", minute, second);

    }

    public static Transform FindInChild(Transform trans, string name)
    {
        var ts = trans.GetComponentsInChildren<Transform>();
        foreach (var t in ts)
        {
            if (t.name == name)
                return t;
        }
        return null;
    }

    public static void SetLayerWithChilds(GameObject gameObject,int layer)
    {
        var ts = gameObject.GetComponentsInChildren<Transform>();
        foreach (var t in ts)
        {
            t.gameObject.layer = layer;

        }
    }

    /// <summary>
    /// 名字只显示八位
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public static string GetShowedName(string name,bool showExtend)
    {
        if (string.IsNullOrEmpty(name)) 
            return "";
        
        if (name.Length > 9)
        {
            name = name.Substring(0, 8);
            if (showExtend)
                name += "...";
        }
        return name;
    }

    public static void SetGameObjLayer(GameObject gameObject, int layerChild)
    {
        foreach (var transform in gameObject.GetComponentsInChildren<Transform>())
        {
            transform.gameObject.layer = layerChild;
        }
    }

    /// <summary>
    /// 旋转
    /// </summary>
    /// <param name="trans"></param>
    /// <param name="center"></param>
    /// <param name="angle"></param>
    public static Vector3 ClockwiseRotateAround(Vector3 pos, Vector3 center, float angle)
    {
        Vector3 p = pos - center;
        Quaternion m = Quaternion.AngleAxis(angle, Vector3.back);
        return center + m * p;
    }  
   
    /*public static Vector3 RotatePoint(Vector3 worldPoint, Vector3 origin, Vector3 axis,float radian)
    {
        Vector3 relativePos = worldPoint - origin;

        Matrix4x4 r = GetRotateMatrix(axis * radian);
        Vector4 p = new Vector4(relativePos.x, relativePos.y, relativePos.z, 1);
        Vector4 temp = r * p;

        Vector3 res = origin + new Vector3(temp.x, temp.y, temp.z);
        //GameDebug.Log($"旋转矩阵 \n{r} \n乘以 向量{p} 得到：{temp}  返回结果:{res}");
        return res;
    }
    public static Matrix4x4 GetRotateMatrix(Vector3 rotate)
    {
        Matrix4x4 zM = GetRotateZMatrix(rotate.z);
        Matrix4x4 yM = GetRotateYMatrix(rotate.y);
        Matrix4x4 xM = GetRotateXMatrix(rotate.x);
        
        Matrix4x4 r = yM * xM * zM;
        // GameDebug.Log($"矩阵 \n{r} \n乘以 矩阵{yM}\n乘以 矩阵\n{yM} 得到：\n{r} ");
        return r;
    }
    public static Matrix4x4 GetRotateXMatrix(float alpha)
    {
        while (alpha < 0)
            alpha += 2 * Mathf.PI;

        alpha %= 2 * Mathf.PI;

        Matrix4x4 RotateXMatrix = new Matrix4x4();
        RotateXMatrix[1, 1] = 1;
        RotateXMatrix[2, 2] = Mathf.Cos(alpha);
        RotateXMatrix[2, 3] = -Mathf.Sin(alpha);
        RotateXMatrix[3, 2] = Mathf.Sin(alpha);
        RotateXMatrix[3, 3] = Mathf.Cos(alpha);
        RotateXMatrix[4, 4] = 1;
        return RotateXMatrix;
    }
    public static Matrix4x4 GetRotateYMatrix(float alpha)
    {
        while (alpha < 0)
            alpha +=  2 * Mathf.PI;

        Matrix4x4 RotateYMatrix = new Matrix4x4();
        RotateYMatrix[1, 1] = Mathf.Cos(alpha);
        RotateYMatrix[1, 3] = Mathf.Sin(alpha);
        RotateYMatrix[2, 2] = 1;
        RotateYMatrix[3, 1] = -Mathf.Sin(alpha);
        RotateYMatrix[3, 3] = Mathf.Cos(alpha);
        RotateYMatrix[4, 4] = 1;
        return RotateYMatrix;
    }

    public static Matrix4x4 GetRotateZMatrix(float alpha)
    {
        while (alpha < 0)
            alpha +=  2 * Mathf.PI;

        Matrix4x4 RotateYMatrix = new Matrix4x4();
        RotateYMatrix[1, 1] = Mathf.Cos(alpha);
        RotateYMatrix[1, 2] = -Mathf.Sin(alpha);
        RotateYMatrix[2, 1] = Mathf.Sin(alpha);
        RotateYMatrix[2, 2] = Mathf.Cos(alpha);
        RotateYMatrix[3, 3] = 1;
        RotateYMatrix[4, 4] = 1;
        return RotateYMatrix;
    }*/

    public static float FloatRound(float value, int round)
    {
        return (int)(value * round) / (float)round;
    }
    
    public static bool CheckBlockWithObj(Vector3 fromPos, Vector3 toPos,out RaycastHit hit,LayerMask layer)
    {
        Vector3 checkBeginPos = fromPos;
        Vector3 checkVec = toPos - fromPos;

        checkBeginPos.y = 1;
        checkVec.y = 0;
        
        Ray checkRay = new Ray(checkBeginPos,checkVec);

        bool rayCast = Physics.Raycast(checkRay,out hit , checkVec.magnitude,layer);

        if (rayCast)
        {
//          GameDebug.LogShowy($"检测碰撞到墙壁:{hit.collider.gameObject.name}");
            return true;
        }
        return false;
    }
}
